package com.sprucetec.livechat.config;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.NamedNode;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ArrayList;

/**
 * Created with IntelliJ IDEA.
 * User: zhangyb
 * Date: 2018/10/11
 * Time: 11:50
 * Description: redis配置类
 **/
@Setter
@Getter
@Configuration
@EnableCaching
@ConfigurationProperties(prefix = "redis")
public class RedisConfig {

    private Integer timeout;    //超时时间
    private boolean usePool;    //是否启用连接池

    private Integer maxIdle;    //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值也是8
    private Integer minIdle;    //
    private Integer maxWaitMillis;    //当borrow一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；
    private Integer minEvictableIdleTimeMillis; //表示一个对象至少停留在idle状态的最短时间，然后才能被idle object evitor扫描并驱逐
    private Integer numTestsPerEvictionRun; //表示idle object evitor每次扫描的最多的对象数；
    private Integer timeBetweenEvictionRunsMillis;//表示idle object evitor两次扫描之间要sleep的毫秒数
    private String masterName;        // master name 不能使用特殊
    private String[] sentinelNode;    //sentinel 集群节点

    @Bean
    public RedisSentinelConfiguration getRedisSentinelConfiguration() {
        RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration();
        NamedNode namedNode = new NamedNode() {
            @Override
            public String getName() {
                return masterName;
            }
        };

        sentinelConfiguration.setMaster(namedNode);
        ArrayList<RedisNode> sentinels = new ArrayList<RedisNode>();
        for (String sentinelNodes : sentinelNode) {
            String host = sentinelNodes.split(":")[0];
            int port = Integer.parseInt(sentinelNodes.split(":")[1]);
            RedisNode redisNode = new RedisNode(host, port);
            sentinels.add(redisNode);
        }
        sentinelConfiguration.setSentinels(sentinels);
        return sentinelConfiguration;
    }

    @Bean(name = "jedisConnFactory")
    public JedisConnectionFactory getJedisConnectionFactory() {
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(getRedisSentinelConfiguration());
        jedisConnectionFactory.setTimeout(timeout);
        jedisConnectionFactory.setUsePool(usePool);
        if (usePool) {
            JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
            jedisPoolConfig.setMaxIdle(maxIdle);
            jedisPoolConfig.setMinIdle(minIdle);
            jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
            jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
            jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
            jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
            jedisConnectionFactory.setPoolConfig(jedisPoolConfig);
        }
        return jedisConnectionFactory;
    }


    @Bean(name = "redisTemplate")
    public RedisTemplate<String,Object> getRedisTemplate() {
        RedisTemplate<String,Object> redisTemplate = new RedisTemplate<String,Object>();
        redisTemplate.setConnectionFactory(getJedisConnectionFactory());
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericFastJsonRedisSerializer());

        return redisTemplate;
    }


   /* @Bean(name = "redisTemplate")
    public RedisTemplate<String, Object> getRedisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(getJedisConnectionFactory());

        //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        //Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
        //使用Fastjson2JsonRedisSerializer来序列化和反序列化redis的value值 by zhengkai
        FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class);

        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);

        redisTemplate.setValueSerializer(serializer);
        //使用StringRedisSerializer来序列化和反序列化redis的key值
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }*/


    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        //cacheManager.setDefaultExpiration(300); // 设置key-value超时时间 5min
        return cacheManager;
    }


}
